require 'merge/field'
require 'math'
#require  'merge/trusts'

module Merge
  
  class SimpleField < Field
    
    def get_probabilistic_field(services)    
      sample_space = get_sample_space services
      #      sample_space.each_pair {|k,v|
      #        puts "#{k} => #{v}"
      #      }
      prob_dist = evalue_prob_dist sample_space
      prob_dist = {} if prob_dist.size == 0 #c'è solo top nello spazio campionario
      prob_dist
    end
    
    protected
    
    def get_sample_space(services)
      sample_space = Hash.new 0.0
      services.each { |s|
        #        if !s.crawl.nil? && !s.crawl.data.nil? then
        data = s.crawl.data
        if data.attribute_present?(name) then
          value = data.send(name)
          sample_space[value] = Math::tsum(sample_space[value],data.trust_of(name)) unless value.nil?
        end
        #        end
      }
      sample_space[:top] = 0.99
      sample_space     
    end
    
    def sim(a,b)
      raise NotImplementedError.new "Subclass must implents this method!!"
    end
    
    def evalue_prob_dist(sample_space)
      values = sample_space.keys
      trusts = sample_space.values
      matrix = Array.new values.size
      prob_dist = Hash.new
      
      for i in (0..values.size - 1) do
        matrix[i] = Array.new(values.size, 0.0)
      end
      for i in (0..values.size - 1) do
        matrix[i][i]  = 0.0
      end
      
      for i in (0..values.size - 1) do
        for j in (0..values.size - 1) do
          if i == j then
            matrix[i][j] = 0.0
          else
            prob = sim(values[i],values[j]) * trusts[i]
            matrix[i][j] = prob
          end
        end
      end
      
      for i in (0..values.size-1) do
        #prob = matrix[i].sum
        prob = 0.0
        matrix[i].each {|e| prob += e}
        prob_dist[values[i]] = prob
      end
      
      sum = 0
      prob_dist.each_pair {|k,v| sum += v}
      prob_dist.each_pair {|k,v| prob_dist[k] = v / sum}
      prob_dist
    end
  end
  
end